﻿/*
 * runtimestamp.cpp
 *
 *  Created on: 2020年4月27日
 *      Author: Dylan.Gao
 */

#include <dm/export.hpp>

#define DM_API_MISC DM_API_EXPORT

#include <dm/runtimestamp.hpp>

#ifdef WIN32
#include <windows.h>
#endif

namespace dm{

CRunTimeStamp CRunTimeStamp::operator-( const CRunTimeStamp& rc )const{
	CRunTimeStamp rt(m_sec-rc.m_sec,m_nsec-rc.m_nsec);
	if( rt.m_nsec<0 ){
		rt.m_nsec += 1000000000l;
		--rt.m_sec;
	}

	return rt;
}

bool CRunTimeStamp::isTimeout( sec_t secs,nsec_t nsecs,const CRunTimeStamp& now )const{
	nsecs += m_nsec;
	if( nsecs>=1000000000l ){
		nsecs -= 1000000000l;
		++secs;
	}

	secs += m_sec;
	return secs<now.m_sec?true:(secs==now.m_sec&&nsecs<now.m_nsec);
}

CRunTimeStamp& CRunTimeStamp::add( sec_t secs,nsec_t nsecs ){
	m_sec += secs;
	m_nsec += nsecs;
	if( m_nsec>1000000000l ){
		++m_sec;
		m_nsec %= 1000000000l;
	}

	return *this;
}

#ifdef WIN32

CRunTimeStamp CRunTimeStamp::cur() {
	LARGE_INTEGER f;
	QueryPerformanceFrequency(&f);

	LARGE_INTEGER t;
	QueryPerformanceCounter(&t);

	double df = double(f.QuadPart);
	df = t.QuadPart / df;

	return CRunTimeStamp(sec_t(df), ((dm::uint64)(df * 1000000))%1000000);
}

#else

/**
 * 获取运行时钟当前值
 * @return
 */
CRunTimeStamp CRunTimeStamp::cur() {
	struct timespec ts;
	if (clock_gettime(CLOCK_MONOTONIC, &ts) == 0)
		return CRunTimeStamp(ts.tv_sec, ts.tv_nsec);
	return CRunTimeStamp();
}

#endif

CTimeStamp CRunTimeStamp::toTimeStamp( const CRunTimeStamp& rNow,CTimeStamp now )const{
	CRunTimeStamp d = rNow-*this;
	now.del(d.m_sec,CTimeStamp::us_t(d.m_nsec/1000));
	return now;
}

}
